package com.chang.bootplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chang.bootplus.base.exception.BusException;
import com.chang.bootplus.base.utils.ApiResponse;
import com.chang.bootplus.base.utils.BeanUtil;
import com.chang.bootplus.base.utils.RedisUtil;
import com.chang.bootplus.entity.MatrixUser;
import com.chang.bootplus.entity.Menu;
import com.chang.bootplus.entity.Role;
import com.chang.bootplus.entity.UserRole;
import com.chang.bootplus.mapper.MatrixUserMapper;
import com.chang.bootplus.mapper.MenuMapper;
import com.chang.bootplus.po.RegisterPO;
import com.chang.bootplus.po.UserInfoPO;
import com.chang.bootplus.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chang
 * @since 2022-01-26
 */
@Service
public class MatrixUserServiceImp extends ServiceImpl<MatrixUserMapper, MatrixUser> implements MatrixUserService {


    @Autowired
    MatrixUserService userService;

    @Autowired
    UserRoleService userRoleService;

    @Autowired
    RoleService roleService;

    @Autowired
    MenuService menuService;

    @Autowired
    MenuMapper menuMapper;

    @Autowired
    MatrixUserMapper matrixUserMapper;

    @Autowired
    RoleMenuService roleMenuService;

    @Autowired
    RedisUtil redisUtil;


    @Override
    public MatrixUser getByUsername(String username) {
        return  getOne(new LambdaQueryWrapper<MatrixUser>().eq(MatrixUser::getUsername,username));
    }
    @Override
    public String getUserAuthorityInfo(Long userId) {
        // 获取到Role_权限字符串，
        List<Role> roles = roleService.list(new QueryWrapper<Role>().inSql("id", "select role_id from user_role where user_id=" + userId));
        String authorityInfo = null;
        // 当前的角色数大于0时处理转化为字符串
        if (redisUtil.get("Authority:"+getById(userId).getUsername())!=null){
            authorityInfo= (String) redisUtil.get("Authority:"+getById(userId).getUsername());
        }else {
            if (roles.size()>0){
                String roleCodes = roles.stream().map(t -> "ROLE_" + t.getCode()).collect(Collectors.joining(","));
                authorityInfo=roleCodes.concat(",");
            }
            // 继续获取权限菜单信息
            List<Long> menuIds= menuMapper.getMenuIds(userId);
            if (menuIds.size()!=0){
                List<Menu> menus = menuService.listByIds(menuIds);
                if (menus.size()>0){
                    String menuPrems=menus.stream().map(t->t.getPerms()).collect(Collectors.joining(","));
                    System.out.println(menuPrems);
                    authorityInfo+=menuPrems;
                }
            }else {
                throw new BusException("没有权限");
            }

            // 将用户信息存储至redis
            redisUtil.set("Authority:"+getById(userId).getUsername(),authorityInfo);
        }

        return authorityInfo;
    }

    @Override
    public ApiResponse<Void> register(RegisterPO po) {
        MatrixUser user = BeanUtil.beanA2beanB(po, MatrixUser.class);
        if (userService.getByUsername(po.getUsername())!=null){
            throw new BusException("该用户已存在");
        }
        String password = po.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(password));
        save(user);
        return new ApiResponse().setReMsg("注册成功");
    }

    @Override
    public void clearAuthorityInfoByMenuId(Long id) {
        List<MatrixUser> users = matrixUserMapper.listByMenuId(id);
        if (users.size()==0){
            throw new BusException("菜单不存在");
        }
        users.stream().forEach(t->{
            clearAuthorityInfoByName(t.getUsername());
        });
    }

    @Override
    public void clearAuthorityInfoByName(String username) {
        redisUtil.del("Authority:"+username);
    }



    @Override
    public void clearAuthorityInfoByRoleId(Long id) {
        List<UserRole> list = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, id));
        List<Long> userIds = list.stream().map(UserRole::getUserId).collect(Collectors.toList());
        userIds.stream().forEach(t->{
            clearAuthorityInfoByName(getById(t).getUsername());
        });

    }

}
